/////////////////////////////////////////////////////////////////
//	File Name	:	"CGame.cpp"
//
//	Author Name	:	Adam Marculaitis (AM)
//
//	Purpose		:	To encapsulate all game related code.
/////////////////////////////////////////////////////////////////
#include "CGame.h"
//#include "IGameState.h"
//#include "CMainMenuState.h"
//#include "CBase.h"
//#include "CEnemy.h"
//#include "CGamePlayState.h"
//#include "COptionsState.h"
//#include "CBullet.h"
//#include "CShip.h"
//#include "CPowerUp.h"
//#include "SGD_Math.h"
//#include "tinyxml/tinyxml.h"

//	Constructor
CGame::CGame(void)
{
	m_pD3D	= NULL;
	m_pTM	= NULL;
	m_pDS	= NULL;
	m_pWM	= NULL;
	m_pDI	= NULL;
//	m_pOM	= NULL;
//	m_pOF	= NULL;
//	m_pMS	= NULL;
//	m_pES	= NULL;
	//m_pCP	= NULL;

	//m_nBGMID = -1;

	//m_nSoundFX = 50;
	//m_nSoundBGM = 50;

	//m_nMaxPlayers = 2;
	//m_nPlayerTurn = 1;
	//for(int i = 0; i < 4; ++i)
	//{
	//	m_nScores[i] = 0;
	//	m_nLives[i] = 3;
	//	m_nDamage[i] = 1;
	//	m_nLevel[i] = 1;
	//}
	//for(int i = 0; i < 10; ++i)
	//{
	//	m_highscores[i].m_nScore = 0;
	//	strcpy(m_highscores[i].m_chName, "AAA");
	//}
}

//	Destructor
CGame::~CGame(void)
{
	//SaveHighScores();
	//SaveSounds();
}

CGame* CGame::GetInstance(void)
{
	//	Lazy instantiation
	static CGame instance;
	return &instance;
}

//bool CGame::LoadHighScores()
//{
//	TiXmlDocument doc;
//
//	if(!doc.LoadFile("resource/data/highscores.xml"))
//	{
//		return false;
//	}
//
//	TiXmlElement* pRoot = doc.RootElement();
//
//	if(!pRoot)
//		return false;
//
//	TiXmlElement* pHighscore = pRoot->FirstChildElement("highscore");
//
//	if(pHighscore)
//	{
//		for(int i = 0; i < 10; ++i)
//		{
//			pHighscore->Attribute("score", &m_highscores[i].m_nScore);
//			strcpy(m_highscores[i].m_chName, pHighscore->GetText());
//			pHighscore = pHighscore->NextSiblingElement("highscore");
//		}
//	}
//
//	return true;
//}
//
//bool CGame::LoadSounds()
//{
//	TiXmlDocument doc;
//
//	// Load the entire xml file into memory
//	if(!doc.LoadFile("resource/data/Options.xml"))
//		return false;
//
//	// open the main directory
//	TiXmlElement* pRoot = doc.RootElement();
//
//	// returns NULL if it couldnt find it
//	if(!pRoot)
//		return false;
//
//	TiXmlElement* pSound = pRoot->FirstChildElement("sound");
//
//	if(pSound)
//	{
//		pSound->Attribute("FXVolume", &m_nSoundFX);
//		pSound->Attribute("GameVolume", &m_nSoundBGM);
//	}
//
//	return true;
//}
//
//bool CGame::SaveHighScores()
//{
//	TiXmlDocument doc;
//
//	TiXmlDeclaration* pDec = new TiXmlDeclaration("1.0", "utf-8", "yes");
//
//	// put the declaration inside the document
//	doc.LinkEndChild(pDec);
//
//	// create root folder
//	TiXmlElement* pHighscores = new TiXmlElement("highscores");
//
//	// put root into document
//	doc.LinkEndChild(pHighscores);
//
//	////////////////////////////////////////////////////////////////////////////////////////////
//	for( int i = 0; i < 10; i++)
//	{
//		TiXmlElement* pHighscore = new TiXmlElement("highscore");
//
//		// fill it out
//		pHighscore->SetAttribute("score", m_highscores[i].m_nScore);
//
//		TiXmlText* pText = new TiXmlText(m_highscores[i].m_chName);
//
//		// put text inside highscore
//		pHighscore->LinkEndChild(pText);
//
//		pHighscores->LinkEndChild(pHighscore);
//	}
//	////////////////////////////////////////////////////////////////////////////////////////////
//
//	// save out the file
//	if( !doc.SaveFile("resource/data/highscores.xml"))
//		return false;
//
//	return true;
//}
//
//bool CGame::SaveSounds()
//{
//	TiXmlDocument doc;
//
//	TiXmlDeclaration* pDec = new TiXmlDeclaration("1.0", "utf-8", "yes");
//
//	// put the declaration inside the document
//	doc.LinkEndChild(pDec);
//
//	// create root folder
//	TiXmlElement* pOptions = new TiXmlElement("options");
//
//	// put root into document
//	doc.LinkEndChild(pOptions);
//
//	TiXmlElement* pSound = new TiXmlElement("sound");
//
//	// fill it out
//	pSound->SetAttribute("FXVolume", this->GetSoundFX());
//
//	pSound->SetAttribute("GameVolume", this->GetSoundBGM());
//
//	pOptions->LinkEndChild(pSound);
//
//	// save out the file
//	if( !doc.SaveFile("resource/data/Options.xml"))
//		return false;
//
//	return true;
//}
//
//
//
//void CGame::SortHighScores()
//{
//	for(int index = 1; index < 10; ++index)
//	{
//		while(m_highscores[index].m_nScore > m_highscores[index - 1].m_nScore)
//		{
//			Highscore temp = m_highscores[index];
//			m_highscores[index] = m_highscores[index - 1];
//			m_highscores[index - 1] = temp;
//			--index;
//			if(!index)
//				break;
//		}
//	}
//}
//
//	3 steps a game goes through in its lifetime

//	1.	Initialization
void CGame::Initialize(HWND hWnd, HINSTANCE hInstance,
					   int nScreenWidth, int nScreenHeight, bool bIsWindowed)
{
	//	Get pointers to singletons:
	m_pD3D	= CSGD_Direct3D::GetInstance();
	m_pTM	= CSGD_TextureManager::GetInstance();
	m_pDS	= CSGD_DirectSound::GetInstance();
	m_pWM	= CSGD_WaveManager::GetInstance();
	m_pDI	= CSGD_DirectInput::GetInstance();
//	m_pOM	= CSGD_ObjectManager::GetInstance();
//	m_pOF	= CSGD_ObjectFactory<string, CBase>::GetInstance();
//	m_pMS	= CSGD_MessageSystem::GetInstance();
//	m_pES	= CSGD_EventSystem::GetInstance();
//	m_pCP	= new CCodeProfiler("resource/data/profile.txt");

	m_nWINDOW_WIDTH = nScreenWidth;
	m_nWINDOW_HEIGHT = nScreenHeight;
	m_bIS_WINDOWED = bIsWindowed;

	//	Initialize singletons:
	m_pD3D->InitDirect3D(hWnd, m_nWINDOW_WIDTH, m_nWINDOW_HEIGHT, m_bIS_WINDOWED, false);
	m_pTM->InitTextureManager( m_pD3D->GetDirect3DDevice(), m_pD3D->GetSprite() );
	m_pDS->InitDirectSound(hWnd);
	m_pWM->InitWaveManager(hWnd, m_pDS->GetDSObject() );
	m_pDI->InitDirectInput(hWnd, hInstance, DI_KEYBOARD | DI_MOUSE);
//	m_pMS->InitMessageSystem(CGame::MessageProc);

	//m_nBGMID = m_pWM->LoadWave("resource/sound/AaB_i_write_sins_not_tragedies.wav");
	
	//m_pWM->SetVolume(m_nBGMID, m_nSoundBGM);
	//m_pWM->Play(m_nBGMID, DSBPLAY_LOOPING);

	//ChangeState(CMainMenuState::GetInstance());

	m_fElapsedTime = 0;
	m_fPreviousTime = (float)GetTickCount();

	/*LoadHighScores();
	SortHighScores();
	LoadSounds();*/
}

//	3.	Clean Up
void CGame::Shutdown(void)
{
	//ChangeState(NULL);
	//ClearAllStates();
	//SAFE_DELETE(m_pCP);
	//if(m_nBGMID>-1)
	//{
	//	m_pWM->UnloadWave(m_nBGMID);
	//	m_nBGMID=-1;
	//}


	//	Shutdown in the opposite order
	//if (m_pES)
	//{
	//	m_pES->ShutdownEventSystem();
	//	m_pES = NULL;
	//}
	//if (m_pMS)
	//{
	//	m_pMS->ShutdownMessageSystem();
	//	m_pMS = NULL;
	//}
	/*if(m_pOF)
	{
		m_pOF->ShutdownObjectFactory();
		m_pOF = NULL;
	}
	if(m_pOM)
	{
		m_pOM->DeleteInstance();
		m_pOM = NULL;
	}*/
	if (m_pDI)
	{
		m_pDI->ShutdownDirectInput();
		m_pDI = NULL;
	}

	if (m_pWM)
	{
		m_pWM->ShutdownWaveManager();
		m_pWM = NULL;
	}

	if (m_pDS)
	{
		m_pDS->ShutdownDirectSound();
		m_pDS = NULL;
	}

	if (m_pTM)
	{
		m_pTM->ShutdownTextureManager();
		m_pTM = NULL;
	}

	if (m_pD3D)
	{
		m_pD3D->ShutdownDirect3D();
		m_pD3D = NULL;
	}
}

//	2.	Execution
bool CGame::Main(void)
{
	m_fElapsedTime = GetTickCount() - m_fPreviousTime;
	m_fPreviousTime += m_fElapsedTime;
	m_fElapsedTime /= 1000.0f;

	//	3 steps a game goes through during execution
	//	1.	Input
	if (Input() == false)
		return false;

	//	2.	Update
	Update();

	//	3.	Draw
	Render();

	return true;
}

bool CGame::Input(void)
{
	//	Updates the state of your input devices
	//	(should only be called ONCE a frame)
	m_pDI->ReadDevices();

	if ( ( m_pDI->KeyDown(DIK_LALT) || m_pDI->KeyDown(DIK_RALT) ) && m_pDI->KeyPressed(DIK_RETURN) )
	{
		SetWindowMode(!m_bIS_WINDOWED);
		return true;
	}


	//return m_pGS[m_pGS.size()-1]->Input();
}

void CGame::Update(void)
{
	//m_pWM->SetVolume(m_nBGMID, m_nSoundBGM);
	//	Clean up excess copies of sounds
	//	that are finished playing
	//	(call only ONCE a frame)
	m_pWM->Update();
	//m_pGS[m_pGS.size()-1]->Update(m_fElapsedTime);
	//m_pES->ProcessEvents();
	//m_pMS->ProcessMessages();
}

void CGame::Render(void)
{
	m_pD3D->Clear(0, 0, 127);

	//for( int i = 0; i < m_pGS.size(); ++i)
	//{
	//	m_pGS[i]->Render();
	//}

	m_pD3D->Present();
}

//void CGame::ChangeState(IGameState *pGS)
//{
//	for( int i = 0; i < m_pGS.size(); ++i)
//	{
//		if(m_pGS[i] != NULL)
//			m_pGS[i]->Exit();
//	}
//	m_pGS.clear();
//	
//	if(pGS != NULL)
//	{
//		m_pGS.push_back(pGS);
//		m_pGS[m_pGS.size()-1]->Enter();
//	}
//}
//void CGame::PushState(IGameState* pState)
//{
//	if(pState != NULL)
//	{
//		m_pGS.push_back(pState);
//		m_pGS[m_pGS.size()-1]->Enter();
//	}
//}
//
//void CGame::PopState()
//{
//	if(m_pGS.size() != 0 && m_pGS[m_pGS.size()-1] != NULL)
//	{
//		m_pGS[m_pGS.size()-1]->Exit();
//	}
//	m_pGS.pop_back();
//}
//
//void CGame::ClearAllStates()
//{
//	for( int i = 0; i < m_pGS.size(); ++i)
//	{
//		if(m_pGS[i] != NULL)
//			m_pGS[i]->Exit();
//	}
//	m_pGS.clear();
//}
//
//void CGame::SetLastHighscore(int nScore, char chName[4]) 
//{
//	m_highscores[9].m_nScore = nScore;
//	strcpy(m_highscores[9].m_chName, chName);
//}
//

void CGame::SetScreenMode(int nScreenWidth, int nScreenHeight, bool bIsWindowed)
{
	m_nWINDOW_WIDTH = nScreenWidth;
	m_nWINDOW_HEIGHT = nScreenHeight;
	m_bIS_WINDOWED = bIsWindowed;

	m_pD3D->ChangeDisplayParam(m_nWINDOW_WIDTH, m_nWINDOW_HEIGHT, m_bIS_WINDOWED);
}

void CGame::SetScreenResolution(int nScreenWidth, int nScreenHeight)
{
	m_nWINDOW_WIDTH = nScreenWidth;
	m_nWINDOW_HEIGHT = nScreenHeight;

	m_pD3D->ChangeDisplayParam(m_nWINDOW_WIDTH, m_nWINDOW_HEIGHT, m_bIS_WINDOWED);
}

void CGame::SetScreenWidth(int nScreenWidth)
{
	m_nWINDOW_WIDTH = nScreenWidth;

	m_pD3D->ChangeDisplayParam(m_nWINDOW_WIDTH, m_nWINDOW_HEIGHT, m_bIS_WINDOWED);
}

void CGame::SetScreenHeight(int nScreenHeight)
{
	m_nWINDOW_HEIGHT = nScreenHeight;

	m_pD3D->ChangeDisplayParam(m_nWINDOW_WIDTH, m_nWINDOW_HEIGHT, m_bIS_WINDOWED);
}

void CGame::SetWindowMode(bool bIsWindowed)
{
	m_bIS_WINDOWED = bIsWindowed;

	m_pD3D->ChangeDisplayParam(m_nWINDOW_WIDTH, m_nWINDOW_HEIGHT, m_bIS_WINDOWED);
}

int CGame::GetScreenWidth()
{
	return m_nWINDOW_WIDTH;
}

int CGame::GetScreenHeight()
{
	return m_nWINDOW_HEIGHT;
}

bool CGame::GetWindowMode()
{
	return m_bIS_WINDOWED;
}

//void CGame::ResetPlayers()
//{
//	m_nPlayerTurn = 1;
//	for(int i = 0; i < 4; ++i)
//	{
//		m_nScores[i] = 0;
//		m_nLives[i] = 3;
//		m_nDamage[i] = 1;
//		m_nLevel[i] = 1;
//	}
//}
//
//void CGame::MessageProc(CBaseMessage* pMsg)
//{
//	switch(pMsg->GetMsgID())
//	{
//	}
//}